package org.jackysoft.entity;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.struts2.json.annotations.JSON;
import org.hibernate.annotations.Type;
import org.jackysoft.entity.AbstractEntity;
import org.jackysoft.entity.Department;
import org.jackysoft.entity.User;
import org.jackysoft.report.ReporterLifecycle;
import org.joda.time.DateTime;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 产品月快报
 */

@MappedSuperclass
public abstract class AbstractReporter  extends AbstractEntity implements Cloneable  {


	/**
	 * 
	 */
	private static final long serialVersionUID = -8402762793273144154L;

	private String title;

	private DateTime updateDate;

	private DateTime createDate;
	
	private User leader;

	private User maker;

	private Department department;

	private String remark;

	private Float increateRate = 0.0f;
	
	private ReporterLifecycle reportLifecycle = ReporterLifecycle.Daily;

	private Double lastCulumateValue = 0d;
	
	private long timeline;
	
	private boolean firstable = false;
	
	private boolean lastable = false;
	
	private boolean finished = false;
	
	private List<ArmItem> armItems = Lists.newArrayList();
	
	private Map<String,List<ArmItem>>  classifiedItems = Maps.newHashMap();
	public AbstractReporter() {
	}
	
	
	
	public AbstractReporter(String id, String title,DateTime createDate, DateTime updateDate,
			User maker, Department department) {
		super();
		this.id = id;
		this.title = title;
		this.updateDate = updateDate;
		this.createDate = createDate;
		this.maker = maker;
		this.department = department;
	}

	public AbstractReporter(String id2, String leader2,
			String reportMakerLocalName, Department unitName,
			String dateString, String remark2, DateTime timestamp) {
	   
	    
	}



	/**
	 * @return remark
	 */
	
	public String getRemark() {
		return remark;
	}

	public void setReportLifecycle(ReporterLifecycle reportLifecycle) {
		this.reportLifecycle = reportLifecycle;
	}



	public ReporterLifecycle getReportLifecycle() {
		return reportLifecycle;
	}



	/**
	 * @param remark
	 *            the remark to set
	 */
	public void setRemark(String remark) {
		this.remark = remark;
	}

	/**
	 * 报表标题
	 */

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	
	/**
	 * 创建时间
	 */
	
	@Type(type = "jodatime")
	public DateTime getUpdateDate() {
		return this.updateDate;
	}

	public void setUpdateDate(DateTime updateDate) {
		this.updateDate = updateDate;
	}

	/**
	 * 单位领导
	 */
	@ManyToOne
	public User getLeader() {
		return this.leader;
	}

	public void setLeader(User unitLeader) {
		this.leader = unitLeader;
	}

	/**
	 * 报表制作者
	 */
	@ManyToOne
	public User getMaker() {
		return this.maker;
	}

	public void setMaker(User reportMaker) {
		this.maker = reportMaker;
	}

	/**
	 * 单位名称
	 */
	@ManyToOne
	public Department getDepartment() {
		return department;
	}

	/**
	 * @param unitName
	 *            the unitName to set
	 */
	public void setDepartment(Department unitName) {
		this.department = unitName;
	}


	public void initialize() {
	}

	
	public void setCreateDate(DateTime createDate) {
		this.createDate = createDate;
	}

	@Type(type = "jodatime")
	public DateTime getCreateDate() {
		return createDate;
	}



	public void setArmItems(List<ArmItem> armItems) {
		this.armItems = armItems;
	}



	/**
	 * 产品上报项目
	 */
	@OneToMany(targetEntity = ArmItem.class,orphanRemoval=true)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.ALL})
	@JoinTable(
			joinColumns = { @JoinColumn(name = "reporter_id")}, 
			inverseJoinColumns = @JoinColumn(name = "armitem_id")		
	)
	@JSON(serialize=false)	
	public List<ArmItem> getArmItems() {
		return armItems;
	}



	public Double getLastCulumateValue() {
		return lastCulumateValue;
	}



	public void setLastCulumateValue(Double lastCulumateValue) {
		this.lastCulumateValue = lastCulumateValue;
	}



	public Float getIncreateRate() {
		return increateRate;
	}



	public void setIncreateRate(Float increateRate) {
		this.increateRate = increateRate;
	}



	@Override
	public String toString() {
		ToStringBuilder.setDefaultStyle(ToStringStyle.MULTI_LINE_STYLE);
		return ToStringBuilder.reflectionToString(this);
	}


    /**
     * 指示此报表是否本月第一张报表
     * */
	public boolean isFirstable() {
		return firstable;
	}



	public void setFirstable(boolean firstable) {
		this.firstable = firstable;
	}


    /**
     * 指示此报表是否本月最后一张报表
     * */
	public boolean isLastable() {
		return lastable;
	}



	public void setLastable(boolean lastable) {
		this.lastable = lastable;
	}



	public long getTimeline() {
		return timeline;
	}



	public void setTimeline(long timeline) {
		this.timeline = timeline;
	}

	@Transient
	public Map<String,List<ArmItem>> getClassifiedItems() {
		if(classifiedItems!=null){
			Set<String> keys = classifiedItems.keySet();
			for(String key : keys){
				List<ArmItem> items = classifiedItems.get(key);
			    Collections.sort(items);
			}
		}
		return classifiedItems;
	}


	public void setClassifiedItems(Map<String,List<ArmItem>> classifiedItems) {
		this.classifiedItems = classifiedItems;
	}



	@Override
	public  AbstractReporter clone() {
		AbstractReporter r = (AbstractReporter) super.clone();
		r.setId(null);
		List<ArmItem> list = Lists.newArrayList();	
		r.setArmItems(list);
		for(ArmItem ai:this.getArmItems()){
			ArmItem cai = ai.clone();
			cai.setId(null);
			r.getArmItems().add(cai);
		}
		
		return r;
	}



	public boolean isFinished() {
		return finished;
	}



	public void setFinished(boolean finished) {
		this.finished = finished;
	}
	
	
	

}
